package com.think.admin.oauth.integration.authenticator.impl;

import com.think.admin.oauth.integration.IntegrationAuthentication;
import com.think.admin.oauth.integration.authenticator.IntegrationAuthenticator;
import com.think.admin.oauth.rbac.RbacGrantedAuthority;
import com.think.admin.oauth.rbac.RbacUserDetails;
import com.think.admin.web.service.IResourceService;
import com.think.admin.web.service.ISysUserService;
import com.think.common.enums.StateEnum;
import com.think.common.utils.SysUtils;
import com.think.dao.entity.SysUser;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.HashSet;
import java.util.Set;

/**
 * <p>
 * 默认认证器：账号密码认证
 * </p>
 * <p>
 * Primary：bean首选者
 *
 * @author: xwj
 * @data: 2019-05-10
 */
public class UsernamePasswordAuthenticator implements IntegrationAuthenticator {
    @Autowired
    ISysUserService sysUserService;
    @Autowired
    IResourceService resourceService;
    @Autowired
    RedissonClient redissonClient;

    @Override
    public UserDetails authenticate(IntegrationAuthentication integrationAuthentication) {
        // 提取用户名
        String username = integrationAuthentication.getUsername();
        if (SysUtils.isEmpty(username)) {
            throw new UsernameNotFoundException("用户信息不存在");
        }

        // 账号没有锁定
        boolean accountNonLocked = true;

        // 查询数据库
        SysUser sysUser = sysUserService.lambdaQuery().eq(SysUser::getUsername, username).one();
        if (SysUtils.isEmpty(sysUser) || SysUtils.isNull(sysUser.getUsername(), sysUser.getPwd())) {
            throw new UsernameNotFoundException("用户名或密码错误");
        }
        if (StateEnum.DISABLE.equals(sysUser.getState())) {
            accountNonLocked = false;
        }

        // 提取 userId
        String userId = sysUser.getUserId();

        // 权限
        Set<RbacGrantedAuthority> authorities = new HashSet<>();

        // 返回
        return new RbacUserDetails(
                userId, sysUser.getUsername(), sysUser.getPwd(),
                sysUser.getType(),
                sysUser.getCompanyId(),
                authorities, accountNonLocked,
                true, true, true);
    }

    @Override
    public void prepare(IntegrationAuthentication integrationAuthentication) {
    }

    @Override
    public void complete(IntegrationAuthentication integrationAuthentication) {
    }

    @Override
    public boolean support(IntegrationAuthentication integrationAuthentication) {
        return false;
    }
}
